package org.aner.tester.generator.data;

import org.aner.tester.exception.NotMatchedException;
import org.slf4j.LoggerFactory;
import org.aner.tester.utils.ReflectUtils;
import org.slf4j.Logger;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * object data generator
 *
 * @author aner
 * @version 1.0
 * @date 2020/12/11 11:42
 */

public class ObjectGenerator {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    private static int nestedLevelCount;

    private FieldGenerator fieldGenerator;

    public ObjectGenerator() {
        fieldGenerator = new FieldGenerator();
    }



    public <T> T generate(Class<T> cls) {
        return generate(cls, 1);
    }

    /**
     * init class data
     * @param cls
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> T generate(Class<T> cls, int levelCount) {
        if (levelCount > nestedLevelCount) {
            return null;
        }
        T bean = null;
        try{
            bean = cls.newInstance();
            Method[] methods = ReflectUtils.getMethods(cls);
            Field[] fields = ReflectUtils.getFields(cls);
            for(Field field:fields){
                String fieldSetName = ReflectUtils.getSetMethodName(field.getName());
                if (!ReflectUtils.checkSetMethod(methods, fieldSetName)) {
                    continue;
                }
                Method fieldSetMethod = cls.getMethod(fieldSetName, field.getType());
                Object value = fieldGenerator.generate(field, levelCount + 1);
                ReflectUtils.setField(bean, fieldSetMethod, value);
            }
        }catch (NotMatchedException e){
            logger.error(e.getMessage() + " in " + bean.getClass());
        }catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }

    public static int getNestedLevelCount() {
        return nestedLevelCount;
    }

    public static void setNestedLevelCount(int nestedLevelCount) {
        ObjectGenerator.nestedLevelCount = nestedLevelCount;
    }

}